package com.qclix.inv.webui;

import com.qclix.inv.Invoice;
import com.qclix.inv.InvoiceService;
import com.qclix.inv.pdf.InvoicePdfGenerationService;
import com.qclix.inv.webui.jsonobj.JSonInvoice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Controller
@RequestMapping(value = "/invoice")
public class InvoiceController {
    private static Logger logger = LoggerFactory.getLogger(InvoiceController.class);

    @Autowired
    private InvoiceService invoiceService;
    @Autowired
    private InvoicePdfGenerationService pdfService;

    public InvoiceService getInvoiceService() {
        return invoiceService;
    }

    public void setInvoiceService(InvoiceService invoiceService) {
        this.invoiceService = invoiceService;
    }

    @RequestMapping(value = "getInvoice", method = RequestMethod.GET)
    public
    @ResponseBody
    JSonInvoice getInvoiceByNumber(@RequestParam String number) {
        logger.info("/invoice/getInvoice path queried with param number = " + number);
        try {
            Invoice invoice = invoiceService.getInvoice(number);
            invoice.setIssueDate(new Date(invoice.getIssueDate().getTime()));
            return JSonObjTranslator.getJSon(invoice);
        } catch (Throwable e) {
            logger.error("Could not retrieve invoice with number = " + number, e);
            return null;
        }

    }

    @RequestMapping(value = "getInvoiceNumbers", method = RequestMethod.GET)
    public
    @ResponseBody
    String[] getInvoicesNumber() {
        logger.info("/invoice/getInvoiceNumbers path queried");

        try {
            List<Invoice> invoices = invoiceService.getLastInvoices(9999);
            String[] numbers = new String[invoices.size()];
            for (int i = 0; i < invoices.size(); i++) {
                numbers[i] = invoices.get(i).getNumber();
            }
            return numbers;
        } catch (Throwable e) {
            logger.error("Could not retrieve last invoices");
            return null;
        }
    }

    @RequestMapping(value = "new-invoice")
    public ModelAndView newInvoicePage() {
        return new ModelAndView("new-invoice");
    }

    @RequestMapping(value = "view-invoice")
    public ModelAndView viewInvoicePage(@RequestParam(required = false) String number) {
        logger.info("/invoice/view-invoice path queried with number = " + number);
        Invoice selectedInvoice = null;
        List<String> numbers = new ArrayList<String>();
        try {
            List<Invoice> invoices = invoiceService.getLastInvoices();
            for (Invoice invoice : invoices) {
                numbers.add(invoice.getNumber());
                if (invoice.getNumber().equals(number)) {
                    selectedInvoice = invoice;
                }
            }
        } catch (Throwable e) {
            logger.error("Could not retrieve last invoices");
            return null;
        }
        ModelAndView modelAndView = new ModelAndView("view-invoice", "numbers", numbers);
        modelAndView.addObject("selectedInvoice", selectedInvoice);
        return modelAndView;
    }

    @RequestMapping(value = "new", method = RequestMethod.POST)
    public
    @ResponseBody
    Map<String, String> newInvoice(@RequestBody JSonInvoice invoice) {
        Invoice domainInvoice = JSonObjTranslator.getModel(invoice);
        logger.debug("Creating " + domainInvoice);
        try {
            if (domainInvoice.getContract()!= null) {
                domainInvoice.setContract(invoiceService.getContract(domainInvoice.getContract().getReference()));
                domainInvoice.getContract().setInvoices(null);
            }
            invoiceService.addInvoice(domainInvoice);
        } catch (Throwable e) {
            logger.error("Could not create " + domainInvoice);
            return null;
        }

        Map<String, String> returnMap = new HashMap<String, String>();
        returnMap.put("invoice_number", domainInvoice.getNumber());
        logger.info(domainInvoice.toString() + " created");
        return returnMap;
    }

    @RequestMapping(value = "download.pdf")
    public ModelAndView getPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String invoice = request.getParameter("invoice");
        response.setContentType("application-pdf");
        try {
            response.getOutputStream().write(pdfService.getPDF(invoiceService.getInvoice(invoice)));
            response.getOutputStream().close();
        } catch (Throwable e) {
            logger.error("Could not retrieve PDF for invoice with number " + invoice, e);
            return null;
        }
        return null;
    }
}
